package gov.pbc.nn.kjgl.software.view;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.service.StartProcessInfo;

import gov.pbc.nn.kjgl.entity.ProjectChange;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.software.dao.ChangeProjectDao;

@Component
public class ChangeProjectPR {

	@Autowired
	private ChangeProjectDao changeProjectDao;

	@Autowired
	@Qualifier(ProcessClient.BEAN_ID)
	private ProcessClient processClient;

	@DataProvider
	public void getProjectChange(Page<ProjectChange> page, Criteria criteria, String id) {
		changeProjectDao.getProjectChange(page, criteria, id);
	}

	@DataProvider
	public void getProjectFile(Page<ProjectFile> page, String id) {
		changeProjectDao.getProjectFile(page, id);
	}

	@DataProvider
	public List<Map<String, Object>> getAssessor() {
		return changeProjectDao.getAssessor();
	}

	@DataProvider
	public List<Map<String, Object>> getXqDeptKz(String xqtcDeptId) {
		return changeProjectDao.getXqDeptKz(xqtcDeptId);
	}

	@DataProvider
	public List<Map<String, Object>> getKjcCz() {
		return changeProjectDao.getKjcCz();
	}

	@Transactional
	@DataResolver
	public void saveProjectChange(ProjectChange projectChange, String Id) throws IOException {
		changeProjectDao.saveProjectChange(projectChange, Id);
	}

	@Transactional
	@Expose
	public void delete(List<String> list) {
		changeProjectDao.delete(list);
	}

	/**
	 * 上传附件
	 * 
	 * @param file
	 * @param parameter
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unused")
	@FileResolver
	@Transactional
	public Object process2(UploadFile file, Map<String, Object> parameter) throws Exception {
		String id = (String) parameter.get("id");
		// 判断问题ID。如果为空，则为新增问题。否则就是修改问题。（修改不能对文件进行修改，所以ProjectFile是新增）
		if (StringUtils.isEmpty(id)) {
			// 问题数据尚未保存，需要将上传文件保存到临时目录中，以后当问题数据保存的时候将临时目录中的该文件转移到实际目录中，并更新文件地址
			Path tmpFile = Files.createTempFile(UUID.randomUUID().toString(), null);// 文件名自动生成。后缀名为null。
			// 文件，文件路径。如果已经存在，就替换原有的文件，然后返回文件路径
			Files.copy(file.getInputStream(), tmpFile, StandardCopyOption.REPLACE_EXISTING);
			return tmpFile.toString();
		} else {
			Path dest = this.changeProjectDao.getRealPath();// 上传文件保存后的实际地址

			// 在实际将文件保存到实际地址前要进行数据库操作，这是为了实现文件保存到磁盘时出现异常时能够使数据库事务回滚。
			ProjectFile pf = new ProjectFile();
			pf.setOwnerId(id);
			pf.setFileName(file.getFileName());
			pf.setPath(dest.toString());
			pf.setType(4);
			this.changeProjectDao.save(pf);

			Files.copy(file.getInputStream(), dest);// 文件真实路径
			return pf;
		}
	}

	/**
	 * 保存添加变更项目 并且提交
	 * 
	 * @param projectProblem
	 * @throws IOException
	 */
	@Transactional
	@DataResolver
	public void saveAndTJ(ProjectChange projectChange, Map<String, Object> map) throws IOException {
		String Id = (String) map.get("Id");
		String czUserName = (String) map.get("czUserName");
		int type = (int) map.get("type");
		EntityState state = EntityUtils.getState(projectChange);
		if (state.equals(EntityState.NEW)) {// 新增的时候执行
			// 保存表数据 新增状态为4,提交状态为5
			projectChange.setState(4);
			projectChange.setProjectId(Id);
			this.changeProjectDao.save(projectChange);
			// 得到 上传文件内容
			List<ProjectFile> files = EntityUtils.getValue(projectChange, "dataSetFile");
			if (files != null) {
				// 声明一个map集合，将临时路径存进去，否则在保存实际路径的时候会将临时路径覆盖
				Map<String, String> tmpMap = new HashMap<String, String>();
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					pf.setOwnerId(projectChange.getId());
					pf.setType(4);
					tmpMap.put("File" + i, pf.getPath());// map存放临时路径,没有保存到数据库中。（缓存）
					pf.setPath(this.changeProjectDao.getRealPath().toString());// 将实际路径保存到数据库中
					this.changeProjectDao.save(pf);
				}
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					String key = "File" + i;
					String tmpPath = tmpMap.get(key);// 根据key 得到临时路径
					this.changeProjectDao.transterFile(tmpPath, pf.getPath());// 临时文件更新为实际路径
				}
			}
		} else if (state.equals(EntityState.MODIFIED)) {
			this.changeProjectDao.update(projectChange);
		}
		if (type == 1) {
			this.commitKjcsh(projectChange, czUserName);
		} else {
			this.commitYwbsh(projectChange);
		}
	}

	/**
	 * 提交到科技处
	 * 
	 * @param project
	 * @param type
	 * @param username
	 */
	@Transactional
	@Expose
	public void commitKjcsh(ProjectChange projectChange, String czUserName) {
		try {
			// Project状态state 为5时表示审核中
			projectChange.setState(5);
			changeProjectDao.update(projectChange);
			StartProcessInfo info = new StartProcessInfo();
			info.setPromoter(ContextHolder.getLoginUserName());
			info.setCompleteStartTask(true);
			info.setBusinessId(projectChange.getId());
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("state", "1");
			map.put("ywgxKz", projectChange.getYwbUsername());
			map.put("KjcCz", czUserName);
			info.setVariables(map);
			processClient.startProcessByName("科技部门提出软件项目变更", info);
		} catch (Exception e) {
			throw e;
			// TODO: handle exception
		}
	}

	/**
	 * 提交到业务部门
	 * 
	 * @param project
	 * @param type
	 * @param username
	 */
	@Transactional
	@Expose
	public void commitYwbsh(ProjectChange projectChange) {
		try {
			// Project状态state 为5时表示审核中
			projectChange.setState(5);
			changeProjectDao.update(projectChange);
			StartProcessInfo info = new StartProcessInfo();
			info.setPromoter(ContextHolder.getLoginUserName());
			info.setCompleteStartTask(true);
			info.setBusinessId(projectChange.getId());
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("state", "2");
			map.put("ywgxKz", projectChange.getYwbUsername());
			info.setVariables(map);
			processClient.startProcessByName("业务部门提出软件项目变更", info);
		} catch (Exception e) {
			throw e;
			// TODO: handle exception
		}
	}

	@Expose
	public boolean getDept(String deptId) {
		return changeProjectDao.getDept(deptId);
	}

}
